<template>
  <div class="media-linker">
    <!-- 链接器头部 -->
    <div class="linker-header">
      <h4>关联管理器</h4>
      <p class="header-description">将媒体文件与活动、日记关联，创建完整的记忆体验</p>
      <div class="header-actions">
        <button class="btn btn-text" @click="refreshSuggestions">
          <svg fill="none" viewBox="0 0 24 24">
            <path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" stroke="currentColor" stroke-width="2"/>
            <path d="M3 3v5h5" stroke="currentColor" stroke-width="2"/>
            <path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" stroke="currentColor" stroke-width="2"/>
            <path d="M21 21v-5h-5" stroke="currentColor" stroke-width="2"/>
          </svg>
          刷新建议
        </button>
        <button class="btn btn-secondary" @click="showBatchLinker = true">
          <svg fill="none" viewBox="0 0 24 24">
            <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" stroke="currentColor" stroke-width="2"/>
            <rect height="4" rx="1" ry="1" stroke="currentColor" stroke-width="2" width="8" x="8" y="2"/>
            <path d="M12 11h4" stroke="currentColor" stroke-width="2"/>
            <path d="M12 16h4" stroke="currentColor" stroke-width="2"/>
            <path d="M8 11h.01" stroke="currentColor" stroke-width="2"/>
            <path d="M8 16h.01" stroke="currentColor" stroke-width="2"/>
          </svg>
          批量关联
        </button>
      </div>
    </div>

    <!-- 智能建议区域 -->
    <div v-if="suggestions.length > 0" class="smart-suggestions">
      <h5>智能关联建议</h5>
      <div class="suggestions-list">
        <div
          v-for="suggestion in suggestions"
          :key="suggestion.type + '-' + suggestion.targetId"
          :class="suggestion.type"
          class="suggestion-card"
        >
          <div class="suggestion-icon">
            <svg v-if="suggestion.type === 'activity'" fill="none" viewBox="0 0 24 24">
              <rect height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2" width="18" x="3" y="4"/>
              <line stroke="currentColor" stroke-width="2" x1="16" x2="16" y1="2" y2="6"/>
              <line stroke="currentColor" stroke-width="2" x1="8" x2="8" y1="2" y2="6"/>
              <line stroke="currentColor" stroke-width="2" x1="3" x2="21" y1="10" y2="10"/>
            </svg>
            <svg v-else-if="suggestion.type === 'diary'" fill="none" viewBox="0 0 24 24">
              <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" stroke="currentColor" stroke-width="2"/>
              <path d="M6.5 2H20v20l-1.586-1.586a2 2 0 0 0-2.828 0L14 22.414a2 2 0 0 1-2.828 0l-1.586-1.586a2 2 0 0 0-2.828 0L5.172 22.414A2 2 0 0 1 2 20.828V6.5A2.5 2.5 0 0 1 4.5 4H6.5V2z"/>
            </svg>
            <svg v-else fill="none" viewBox="0 0 24 24">
              <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
              <polyline points="12,6 12,12 16,14" stroke="currentColor" stroke-width="2"/>
            </svg>
          </div>
          <div class="suggestion-content">
            <div class="suggestion-header">
              <h6>{{ suggestion.title }}</h6>
              <div :class="getConfidenceLevel(suggestion.confidence)" class="confidence-badge">
                {{ Math.round(suggestion.confidence * 100) }}%
              </div>
            </div>
            <p class="suggestion-description">{{ suggestion.description }}</p>
            <div class="suggestion-reason">
              <svg fill="none" viewBox="0 0 24 24">
                <path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="2"/>
              </svg>
              {{ suggestion.reason }}
            </div>
            <div class="related-items">
              <span
                v-for="item in suggestion.relatedItems.media.slice(0, 3)"
                :key="item.id"
                class="related-item"
              >
                {{ item.fileName }}
              </span>
              <span v-if="suggestion.relatedItems.media.length > 3" class="more-items">
                +{{ suggestion.relatedItems.media.length - 3 }}
              </span>
            </div>
          </div>
          <div class="suggestion-actions">
            <button
              class="btn btn-sm btn-primary"
              @click="applySuggestion(suggestion)"
            >
              应用
            </button>
            <button
              class="btn btn-sm btn-text"
              @click="dismissSuggestion(suggestion)"
            >
              忽略
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 当前关联显示 -->
    <div class="current-associations">
      <div class="associations-header">
        <h5>当前关联</h5>
        <div class="filter-tabs">
          <button
            v-for="tab in associationTabs"
            :key="tab.key"
            :class="{ active: activeTab === tab.key }"
            class="tab-btn"
            @click="activeTab = tab.key"
          >
            <component :is="tab.icon" />
            {{ tab.label }}
            <span class="count">{{ getAssociationCount(tab.key) }}</span>
          </button>
        </div>
      </div>

      <!-- 活动关联 -->
      <div v-if="activeTab === 'activities'" class="associations-content">
        <div v-if="activityAssociations.length === 0" class="empty-state">
          <svg fill="none" viewBox="0 0 24 24">
            <rect height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2" width="18" x="3" y="4"/>
            <line stroke="currentColor" stroke-width="2" x1="16" x2="16" y1="2" y2="6"/>
            <line stroke="currentColor" stroke-width="2" x1="8" x2="8" y1="2" y2="6"/>
            <line stroke="currentColor" stroke-width="2" x1="3" x2="21" y1="10" y2="10"/>
          </svg>
          <p>暂无关联活动</p>
          <button class="btn btn-primary" @click="showActivityPicker = true">
            关联活动
          </button>
        </div>
        <div v-else class="association-list">
          <div
            v-for="association in activityAssociations"
            :key="association.id"
            class="association-item activity"
          >
            <div class="association-preview">
              <div class="media-thumbnails">
                <img
                  v-for="media in association.media.slice(0, 3)"
                  :key="media.id"
                  :alt="media.fileName"
                  :src="media.thumbnailUrl"
                />
                <div v-if="association.media.length > 3" class="more-count">
                  +{{ association.media.length - 3 }}
                </div>
              </div>
            </div>
            <div class="association-info">
              <h6>{{ getActivityTitle(association.activityId) }}</h6>
              <p v-if="association.description">{{ association.description }}</p>
              <div class="association-meta">
                <span class="media-count">{{ association.media.length }} 个媒体文件</span>
                <span class="create-time">{{ formatDate(association.createTime) }}</span>
              </div>
            </div>
            <div class="association-actions">
              <button
                class="action-btn"
                title="编辑关联"
                @click="editAssociation(association)"
              >
                <svg fill="none" viewBox="0 0 24 24">
                  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2"/>
                  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
              <button
                class="action-btn delete"
                title="移除关联"
                @click="removeAssociation(association)"
              >
                <svg fill="none" viewBox="0 0 24 24">
                  <polyline points="3,6 5,6 21,6" stroke="currentColor" stroke-width="2"/>
                  <path d="M19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 日记关联 -->
      <div v-if="activeTab === 'diaries'" class="associations-content">
        <div v-if="diaryAssociations.length === 0" class="empty-state">
          <svg fill="none" viewBox="0 0 24 24">
            <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" stroke="currentColor" stroke-width="2"/>
            <path d="M6.5 2H20v20l-1.586-1.586a2 2 0 0 0-2.828 0L14 22.414a2 2 0 0 1-2.828 0l-1.586-1.586a2 2 0 0 0-2.828 0L5.172 22.414A2 2 0 0 1 2 20.828V6.5A2.5 2.5 0 0 1 4.5 4H6.5V2z"/>
          </svg>
          <p>暂无关联日记</p>
          <button class="btn btn-primary" @click="showDiaryPicker = true">
            关联日记
          </button>
        </div>
        <div v-else class="association-list">
          <div
            v-for="association in diaryAssociations"
            :key="association.id"
            class="association-item diary"
          >
            <div class="association-preview">
              <div class="media-thumbnails">
                <img
                  v-for="media in association.media.slice(0, 3)"
                  :key="media.id"
                  :alt="media.fileName"
                  :src="media.thumbnailUrl"
                />
                <div v-if="association.media.length > 3" class="more-count">
                  +{{ association.media.length - 3 }}
                </div>
              </div>
            </div>
            <div class="association-info">
              <h6>{{ getDiaryTitle(association.diaryId) }}</h6>
              <p v-if="association.caption">{{ association.caption }}</p>
              <div class="association-meta">
                <span :class="association.position" class="position-tag">
                  {{ association.position === 'inline' ? '正文中' : '附件' }}
                </span>
                <span class="media-count">{{ association.media.length }} 个媒体文件</span>
                <span class="create-time">{{ formatDate(association.createTime) }}</span>
              </div>
            </div>
            <div class="association-actions">
              <button
                class="action-btn"
                title="编辑关联"
                @click="editAssociation(association)"
              >
                <svg fill="none" viewBox="0 0 24 24">
                  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2"/>
                  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
              <button
                class="action-btn delete"
                title="移除关联"
                @click="removeAssociation(association)"
              >
                <svg fill="none" viewBox="0 0 24 24">
                  <polyline points="3,6 5,6 21,6" stroke="currentColor" stroke-width="2"/>
                  <path d="M19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 时间线节点 -->
      <div v-if="activeTab === 'timeline'" class="associations-content">
        <div v-if="timelineNodes.length === 0" class="empty-state">
          <svg fill="none" viewBox="0 0 24 24">
            <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
            <polyline points="12,6 12,12 16,14" stroke="currentColor" stroke-width="2"/>
          </svg>
          <p>暂无时间线节点</p>
          <button class="btn btn-primary" @click="createTimelineNode">
            创建节点
          </button>
        </div>
        <div v-else class="timeline-list">
          <div
            v-for="node in timelineNodes"
            :key="node.id"
            class="timeline-node"
          >
            <div class="node-date">
              <div class="date-display">{{ formatDateShort(node.eventDate) }}</div>
            </div>
            <div class="node-content">
              <h6>{{ node.title }}</h6>
              <p v-if="node.description">{{ node.description }}</p>
              <div class="node-stats">
                <span v-if="node.mediaCount > 0" class="stat-item">
                  <svg fill="none" viewBox="0 0 24 24">
                    <rect height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2" width="18" x="3" y="3"/>
                    <circle cx="8.5" cy="8.5" r="1.5" stroke="currentColor" stroke-width="2"/>
                    <polyline points="21,15 16,10 5,21" stroke="currentColor" stroke-width="2"/>
                  </svg>
                  {{ node.mediaCount }}
                </span>
                <span v-if="node.activityCount > 0" class="stat-item">
                  <svg fill="none" viewBox="0 0 24 24">
                    <rect height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2" width="18" x="3" y="4"/>
                    <line stroke="currentColor" stroke-width="2" x1="16" x2="16" y1="2" y2="6"/>
                    <line stroke="currentColor" stroke-width="2" x1="8" x2="8" y1="2" y2="6"/>
                    <line stroke="currentColor" stroke-width="2" x1="3" x2="21" y1="10" y2="10"/>
                  </svg>
                  {{ node.activityCount }}
                </span>
                <span v-if="node.diaryCount > 0" class="stat-item">
                  <svg fill="none" viewBox="0 0 24 24">
                    <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" stroke="currentColor" stroke-width="2"/>
                    <path d="M6.5 2H20v20l-1.586-1.586a2 2 0 0 0-2.828 0L14 22.414a2 2 0 0 1-2.828 0l-1.586-1.586a2 2 0 0 0-2.828 0L5.172 22.414A2 2 0 0 1 2 20.828V6.5A2.5 2.5 0 0 1 4.5 4H6.5V2z"/>
                  </svg>
                  {{ node.diaryCount }}
                </span>
              </div>
              <div v-if="node.tags.length > 0" class="node-tags">
                <span v-for="tag in node.tags" :key="tag" class="tag">{{ tag }}</span>
              </div>
            </div>
            <div class="node-actions">
              <button class="action-btn" @click="editTimelineNode(node)">
                <svg fill="none" viewBox="0 0 24 24">
                  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2"/>
                  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
              <button class="action-btn delete" @click="deleteTimelineNode(node)">
                <svg fill="none" viewBox="0 0 24 24">
                  <polyline points="3,6 5,6 21,6" stroke="currentColor" stroke-width="2"/>
                  <path d="M19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2" stroke="currentColor" stroke-width="2"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 批量关联对话框 -->
    <div v-if="showBatchLinker" class="batch-linker-modal" @click="closeBatchLinker">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h4>批量关联</h4>
          <button class="modal-close" @click="closeBatchLinker">×</button>
        </div>
        <div class="modal-body">
          <BatchAssociationForm
            :selectedMedia="selectedMedia"
            @associated="onBatchAssociated"
            @cancel="closeBatchLinker"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { Message } from '@opentiny/vue'
import {
  getSmartAssociations,
  attachMediaToActivity,
  attachMediaToDiary,
  createTimelineNode,
  getMediaActivities,
  getMediaDiaries,
  detachMediaFromActivity,
  detachMediaFromDiary
} from '@/api/integration'
import BatchAssociationForm from './BatchAssociationForm.vue'

interface Props {
  selectedMedia: any[]
  mode?: 'picker' | 'manager'
}

const props = withDefaults(defineProps<Props>(), {
  mode: 'manager'
})

const emit = defineEmits(['associated', 'updated'])

// 响应式数据
const activeTab = ref('activities')
const showBatchLinker = ref(false)
const showActivityPicker = ref(false)
const showDiaryPicker = ref(false)
const suggestions = ref<any[]>([])
const activityAssociations = ref<any[]>([])
const diaryAssociations = ref<any[]>([])
const timelineNodes = ref<any[]>([])

// 标签页配置
const associationTabs = [
  { key: 'activities', label: '活动', icon: 'IconCalendar' },
  { key: 'diaries', label: '日记', icon: 'IconBook' },
  { key: 'timeline', label: '时间线', icon: 'IconClock' }
]

// 计算属性
const getAssociationCount = (type: string) => {
  switch (type) {
    case 'activities':
      return activityAssociations.value.length
    case 'diaries':
      return diaryAssociations.value.length
    case 'timeline':
      return timelineNodes.value.length
    default:
      return 0
  }
}

const getConfidenceLevel = (confidence: number) => {
  if (confidence >= 0.8) return 'high'
  if (confidence >= 0.6) return 'medium'
  return 'low'
}

// 方法
const refreshSuggestions = async () => {
  if (props.selectedMedia.length === 0) return

  try {
    const mediaIds = props.selectedMedia.map(m => m.id)
    const response = await getSmartAssociations(mediaIds)
    if (response.code === 200) {
      suggestions.value = response.data
    }
  } catch (error) {
    console.error('获取智能建议失败:', error)
  }
}

const applySuggestion = async (suggestion: any) => {
  try {
    const mediaIds = props.selectedMedia.map(m => m.id)

    if (suggestion.type === 'activity') {
      await attachMediaToActivity({
        activityId: suggestion.targetId,
        mediaIds,
        description: suggestion.suggestedAction
      })
    } else if (suggestion.type === 'diary') {
      await attachMediaToDiary({
        diaryId: suggestion.targetId,
        mediaIds,
        caption: suggestion.suggestedAction
      })
    }

    Message.success('关联成功')
    await loadAssociations()
    dismissSuggestion(suggestion)
    emit('associated', { type: suggestion.type, targetId: suggestion.targetId })
  } catch (error) {
    Message.error('关联失败')
    console.error('应用建议失败:', error)
  }
}

const dismissSuggestion = (suggestion: any) => {
  suggestions.value = suggestions.value.filter(
    s => !(s.type === suggestion.type && s.targetId === suggestion.targetId)
  )
}

const loadAssociations = async () => {
  if (props.selectedMedia.length === 0) return

  try {
    // 加载活动关联
    for (const media of props.selectedMedia) {
      const activitiesResponse = await getMediaActivities(media.id)
      if (activitiesResponse.code === 200) {
        // 合并到活动关联列表
      }
    }

    // 加载日记关联
    for (const media of props.selectedMedia) {
      const diariesResponse = await getMediaDiaries(media.id)
      if (diariesResponse.code === 200) {
        // 合并到日记关联列表
      }
    }
  } catch (error) {
    console.error('加载关联失败:', error)
  }
}

const removeAssociation = async (association: any) => {
  if (!confirm('确定要移除此关联吗？')) return

  try {
    const mediaIds = association.media.map(m => m.id)

    if (association.activityId) {
      await detachMediaFromActivity(association.activityId, mediaIds)
      activityAssociations.value = activityAssociations.value.filter(
        a => a.id !== association.id
      )
    } else if (association.diaryId) {
      await detachMediaFromDiary(association.diaryId, mediaIds)
      diaryAssociations.value = diaryAssociations.value.filter(
        a => a.id !== association.id
      )
    }

    Message.success('关联已移除')
    emit('updated')
  } catch (error) {
    Message.error('移除关联失败')
    console.error('移除关联失败:', error)
  }
}

const editAssociation = (association: any) => {
  // 打开编辑关联对话框
  console.log('编辑关联:', association)
}

const createTimelineNode = () => {
  // 打开创建时间线节点对话框
  console.log('创建时间线节点')
}

const editTimelineNode = (node: any) => {
  // 编辑时间线节点
  console.log('编辑时间线节点:', node)
}

const deleteTimelineNode = async (node: any) => {
  if (!confirm('确定要删除此时间线节点吗？')) return

  try {
    // await deleteTimelineNode(node.id)
    timelineNodes.value = timelineNodes.value.filter(n => n.id !== node.id)
    Message.success('时间线节点已删除')
  } catch (error) {
    Message.error('删除失败')
  }
}

const closeBatchLinker = () => {
  showBatchLinker.value = false
}

const onBatchAssociated = (result: any) => {
  Message.success('批量关联成功')
  loadAssociations()
  closeBatchLinker()
  emit('associated', result)
}

const getActivityTitle = (activityId: number) => {
  // 从活动数据中获取标题
  return `活动 ${activityId}`
}

const getDiaryTitle = (diaryId: number) => {
  // 从日记数据中获取标题
  return `日记 ${diaryId}`
}

const formatDate = (date: string | Date) => {
  return new Date(date).toLocaleDateString('zh-CN')
}

const formatDateShort = (date: string | Date) => {
  const d = new Date(date)
  return `${d.getMonth() + 1}/${d.getDate()}`
}

// 监听选中媒体变化
watch(() => props.selectedMedia, () => {
  loadAssociations()
  refreshSuggestions()
}, { immediate: true })

// 初始化
onMounted(() => {
  // 模拟数据
  activityAssociations.value = [
    {
      id: 1,
      activityId: 101,
      description: '春节聚会精彩瞬间',
      createTime: '2024-01-20',
      media: [
        { id: 1, fileName: 'family_photo.jpg', thumbnailUrl: 'https://images.unsplash.com/photo-1511632765486-a01980e01a18?w=100&h=100&fit=crop' }
      ]
    }
  ]

  diaryAssociations.value = [
    {
      id: 1,
      diaryId: 201,
      caption: '今天的心情记录',
      position: 'inline',
      createTime: '2024-01-19',
      media: [
        { id: 2, fileName: 'sunset.jpg', thumbnailUrl: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=100&h=100&fit=crop' }
      ]
    }
  ]

  timelineNodes.value = [
    {
      id: 1,
      title: '春节家庭聚会',
      description: '全家人一起过春节的美好时光',
      eventDate: '2024-01-20',
      tags: ['春节', '家庭', '聚会'],
      mediaCount: 5,
      activityCount: 1,
      diaryCount: 2
    }
  ]
})
</script>

<style lang="scss" scoped>
.media-linker {
  display: flex;
  flex-direction: column;
  gap: 2rem;

  .linker-header {
    text-align: center;

    h4 {
      font-size: 1.2rem;
      font-weight: 600;
      color: #1e293b;
      margin: 0 0 0.5rem 0;
    }

    .header-description {
      color: #64748b;
      margin: 0 0 1.5rem 0;
      font-size: 0.9rem;
    }

    .header-actions {
      display: flex;
      gap: 1rem;
      justify-content: center;

      .btn {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.5rem 1rem;
        border-radius: 8px;
        font-size: 0.9rem;
        cursor: pointer;
        transition: all 0.2s ease;

        svg {
          width: 16px;
          height: 16px;
        }

        &.btn-text {
          background: none;
          border: 1px solid #e2e8f0;
          color: #64748b;

          &:hover {
            background: #f8fafc;
            color: #374151;
          }
        }

        &.btn-secondary {
          background: #f1f5f9;
          border: 1px solid #cbd5e1;
          color: #475569;

          &:hover {
            background: #e2e8f0;
          }
        }
      }
    }
  }

  .smart-suggestions {
    h5 {
      font-size: 1rem;
      font-weight: 600;
      color: #1e293b;
      margin: 0 0 1rem 0;
    }

    .suggestions-list {
      display: flex;
      flex-direction: column;
      gap: 1rem;

      .suggestion-card {
        display: flex;
        align-items: center;
        gap: 1rem;
        padding: 1rem;
        background: white;
        border: 1px solid #e2e8f0;
        border-radius: 12px;
        transition: all 0.2s ease;

        &:hover {
          border-color: #cbd5e1;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
        }

        &.activity {
          border-left-color: #3b82f6;
          border-left-width: 4px;
        }

        &.diary {
          border-left-color: #10b981;
          border-left-width: 4px;
        }

        &.timeline {
          border-left-color: #f59e0b;
          border-left-width: 4px;
        }

        .suggestion-icon {
          width: 48px;
          height: 48px;
          background: #f8fafc;
          border-radius: 12px;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-shrink: 0;

          svg {
            width: 24px;
            height: 24px;
            color: #64748b;
          }
        }

        .suggestion-content {
          flex: 1;
          min-width: 0;

          .suggestion-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 0.5rem;

            h6 {
              font-size: 0.95rem;
              font-weight: 600;
              color: #1e293b;
              margin: 0;
            }

            .confidence-badge {
              padding: 0.25rem 0.5rem;
              border-radius: 12px;
              font-size: 0.75rem;
              font-weight: 500;

              &.high {
                background: rgba(16, 185, 129, 0.1);
                color: #10b981;
              }

              &.medium {
                background: rgba(245, 158, 11, 0.1);
                color: #f59e0b;
              }

              &.low {
                background: rgba(107, 114, 128, 0.1);
                color: #6b7280;
              }
            }
          }

          .suggestion-description {
            color: #64748b;
            font-size: 0.85rem;
            margin: 0 0 0.5rem 0;
          }

          .suggestion-reason {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            color: #10b981;
            font-size: 0.8rem;
            margin-bottom: 0.5rem;

            svg {
              width: 12px;
              height: 12px;
            }
          }

          .related-items {
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;

            .related-item,
            .more-items {
              padding: 0.25rem 0.5rem;
              background: rgba(59, 130, 246, 0.1);
              color: #3b82f6;
              border-radius: 8px;
              font-size: 0.75rem;
            }

            .more-items {
              background: rgba(107, 114, 128, 0.1);
              color: #6b7280;
            }
          }
        }

        .suggestion-actions {
          display: flex;
          gap: 0.5rem;

          .btn-sm {
            padding: 0.5rem 1rem;
            font-size: 0.8rem;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s ease;

            &.btn-primary {
              background: #3b82f6;
              color: white;
              border: 1px solid #3b82f6;

              &:hover {
                background: #2563eb;
              }
            }

            &.btn-text {
              background: none;
              border: none;
              color: #64748b;

              &:hover {
                color: #374151;
              }
            }
          }
        }
      }
    }
  }

  .current-associations {
    .associations-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 1.5rem;

      h5 {
        font-size: 1rem;
        font-weight: 600;
        color: #1e293b;
        margin: 0;
      }

      .filter-tabs {
        display: flex;
        gap: 0.5rem;

        .tab-btn {
          display: flex;
          align-items: center;
          gap: 0.5rem;
          padding: 0.5rem 1rem;
          background: none;
          border: 1px solid #e2e8f0;
          border-radius: 8px;
          cursor: pointer;
          color: #64748b;
          font-size: 0.9rem;
          transition: all 0.2s ease;

          &:hover {
            background: #f8fafc;
            color: #374151;
          }

          &.active {
            background: #3b82f6;
            color: white;
            border-color: #3b82f6;
          }

          .count {
            background: rgba(255, 255, 255, 0.2);
            padding: 0.25rem 0.5rem;
            border-radius: 12px;
            font-size: 0.75rem;
            font-weight: 500;
          }

          &.active .count {
            background: rgba(255, 255, 255, 0.2);
          }
        }
      }
    }

    .associations-content {
      .empty-state {
        text-align: center;
        padding: 3rem 2rem;
        color: #64748b;

        svg {
          width: 48px;
          height: 48px;
          margin-bottom: 1rem;
          opacity: 0.5;
        }

        p {
          margin: 0 0 1.5rem 0;
          font-size: 0.9rem;
        }

        .btn-primary {
          background: #3b82f6;
          color: white;
          border: 1px solid #3b82f6;
          padding: 0.75rem 1.5rem;
          border-radius: 8px;
          cursor: pointer;

          &:hover {
            background: #2563eb;
          }
        }
      }

      .association-list {
        display: flex;
        flex-direction: column;
        gap: 1rem;

        .association-item {
          display: flex;
          align-items: center;
          gap: 1rem;
          padding: 1rem;
          background: white;
          border: 1px solid #e2e8f0;
          border-radius: 12px;

          &.activity {
            border-left-color: #3b82f6;
            border-left-width: 4px;
          }

          &.diary {
            border-left-color: #10b981;
            border-left-width: 4px;
          }

          .association-preview {
            .media-thumbnails {
              position: relative;
              width: 60px;
              height: 60px;

              img {
                position: absolute;
                width: 48px;
                height: 48px;
                border-radius: 6px;
                object-fit: cover;
                border: 2px solid white;

                &:nth-child(1) { top: 0; left: 0; z-index: 3; }
                &:nth-child(2) { top: 6px; left: 6px; z-index: 2; }
                &:nth-child(3) { top: 12px; left: 12px; z-index: 1; }
              }

              .more-count {
                position: absolute;
                bottom: 0;
                right: 0;
                width: 20px;
                height: 20px;
                background: #3b82f6;
                color: white;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 0.7rem;
                font-weight: 600;
              }
            }
          }

          .association-info {
            flex: 1;

            h6 {
              font-size: 0.95rem;
              font-weight: 600;
              color: #1e293b;
              margin: 0 0 0.5rem 0;
            }

            p {
              color: #64748b;
              font-size: 0.85rem;
              margin: 0 0 0.5rem 0;
            }

            .association-meta {
              display: flex;
              gap: 1rem;
              font-size: 0.75rem;
              color: #6b7280;

              .position-tag {
                padding: 0.25rem 0.5rem;
                border-radius: 8px;
                font-weight: 500;

                &.inline {
                  background: rgba(16, 185, 129, 0.1);
                  color: #10b981;
                }

                &.attachment {
                  background: rgba(107, 114, 128, 0.1);
                  color: #6b7280;
                }
              }
            }
          }

          .association-actions {
            display: flex;
            gap: 0.5rem;

            .action-btn {
              width: 32px;
              height: 32px;
              background: none;
              border: 1px solid #e2e8f0;
              border-radius: 6px;
              cursor: pointer;
              color: #64748b;
              display: flex;
              align-items: center;
              justify-content: center;
              transition: all 0.2s ease;

              &:hover {
                background: #f8fafc;
                color: #374151;
              }

              &.delete {
                color: #ef4444;

                &:hover {
                  background: rgba(239, 68, 68, 0.1);
                }
              }

              svg {
                width: 14px;
                height: 14px;
              }
            }
          }
        }
      }

      .timeline-list {
        display: flex;
        flex-direction: column;
        gap: 1rem;

        .timeline-node {
          display: flex;
          align-items: flex-start;
          gap: 1rem;
          padding: 1rem;
          background: white;
          border: 1px solid #e2e8f0;
          border-radius: 12px;
          border-left-color: #f59e0b;
          border-left-width: 4px;

          .node-date {
            .date-display {
              width: 48px;
              height: 48px;
              background: #f59e0b;
              color: white;
              border-radius: 50%;
              display: flex;
              align-items: center;
              justify-content: center;
              font-size: 0.8rem;
              font-weight: 600;
            }
          }

          .node-content {
            flex: 1;

            h6 {
              font-size: 0.95rem;
              font-weight: 600;
              color: #1e293b;
              margin: 0 0 0.5rem 0;
            }

            p {
              color: #64748b;
              font-size: 0.85rem;
              margin: 0 0 0.75rem 0;
            }

            .node-stats {
              display: flex;
              gap: 1rem;
              margin-bottom: 0.5rem;

              .stat-item {
                display: flex;
                align-items: center;
                gap: 0.25rem;
                font-size: 0.75rem;
                color: #6b7280;

                svg {
                  width: 12px;
                  height: 12px;
                }
              }
            }

            .node-tags {
              display: flex;
              gap: 0.5rem;
              flex-wrap: wrap;

              .tag {
                padding: 0.25rem 0.5rem;
                background: rgba(245, 158, 11, 0.1);
                color: #f59e0b;
                border-radius: 8px;
                font-size: 0.75rem;
              }
            }
          }

          .node-actions {
            display: flex;
            gap: 0.5rem;

            .action-btn {
              width: 32px;
              height: 32px;
              background: none;
              border: 1px solid #e2e8f0;
              border-radius: 6px;
              cursor: pointer;
              color: #64748b;
              display: flex;
              align-items: center;
              justify-content: center;
              transition: all 0.2s ease;

              &:hover {
                background: #f8fafc;
                color: #374151;
              }

              &.delete {
                color: #ef4444;

                &:hover {
                  background: rgba(239, 68, 68, 0.1);
                }
              }

              svg {
                width: 14px;
                height: 14px;
              }
            }
          }
        }
      }
    }
  }
}

// 模态框样式
.batch-linker-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;

  .modal-content {
    background: white;
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    width: 90%;
    max-width: 600px;
    max-height: 90vh;
    overflow: hidden;

    .modal-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 1.5rem 2rem;
      border-bottom: 1px solid #e2e8f0;

      h4 {
        font-size: 1.1rem;
        font-weight: 600;
        color: #1e293b;
        margin: 0;
      }

      .modal-close {
        width: 32px;
        height: 32px;
        background: none;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        color: #64748b;
        font-size: 1.2rem;

        &:hover {
          background: #f8fafc;
        }
      }
    }

    .modal-body {
      padding: 2rem;
      overflow-y: auto;
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .media-linker {
    .linker-header .header-actions {
      flex-direction: column;
      gap: 0.5rem;

      .btn {
        width: 100%;
        justify-content: center;
      }
    }

    .suggestions-list .suggestion-card {
      flex-direction: column;
      text-align: center;

      .suggestion-actions {
        width: 100%;
        justify-content: center;
      }
    }

    .associations-header {
      flex-direction: column;
      align-items: stretch;
      gap: 1rem;

      .filter-tabs {
        justify-content: center;
      }
    }

    .association-list .association-item {
      flex-direction: column;
      text-align: center;

      .association-actions {
        justify-content: center;
      }
    }

    .timeline-list .timeline-node {
      flex-direction: column;
      text-align: center;

      .node-actions {
        justify-content: center;
      }
    }
  }
}
</style>
